/**********************************************************************************************/
/* FBL_Value_DateTime.h 	                                               					  */
/*                                                                       					  */
/* Copyright Paradigma, 1993-2006															  */
/* All Rights Reserved                                                   					  */
/**********************************************************************************************/

#ifndef _FBL_Value_DateTime_h
	#define _FBL_Value_DateTime_h
#pragma once

#include <VShared/FBL/publ/Interfaces/FBL_I_ValueDateTime.h>

// FBL:
#include <VShared/FBL/publ/Values/FBL_Value_Numeric.h>

#include <VShared/FBL/publ/Headers/FBL_pre_header.h>


/**********************************************************************************************/
FBL_Begin_Namespace


/**********************************************************************************************/
SMART_CLASS(Value_datetime);
SMART_CLASS(Value_datetime_null);


/**********************************************************************************************/
union DateTimeEncoded;


/**********************************************************************************************/
// FAST STR => DATETIME
//
FBL_SHARED_EXP ushort Convert_str_datetime_aa_fast(
	const char*			inString,
	const DTFormat*		inFormat,
	DateTimeEncoded&	outDateTimeEnc );

FBL_SHARED_EXP ushort Convert_str_datetime_uu_fast( 
	const UChar*		inString,
	const UChar*		inStrEnd,
	const DTFormat*		inFormat,
	DateTimeEncoded&	outDateTimeEnc );


/**********************************************************************************************/
// FAST DATETIME => STR
//
FBL_SHARED_EXP tslen Convert_datetime_str_fast( 
	const DateTimeEncoded&	inDateTimeEnc, 
	EDateFormat				inDateFormat, 
	const char				inDateSep, 
	const char				inTimeSep, 
	char*					outString );

FBL_SHARED_EXP tslen Convert_datetime_str_fast( 
	const DateTimeEncoded&	inDateTimeEnc,
	EDateFormat				inDateFormat,
	const UChar				inDateSep,
	const UChar				inTimeSep,
	UChar*					outString );


/**********************************************************************************************/
// CONVERT with CHECKS
//
FBL_SHARED_EXP void Convert_str_datetime_aa_aux( 
	const char*			inStr,
	const DTFormat* 	inDTFormat,
	DateTimeEncoded&	ioDateTime );

FBL_SHARED_EXP void Convert_str_datetime_uu_aux( 
	const UChar*		inStr,
	const UChar*		InStrEnd,
	const DTFormat* 	inDTFormat,
	DateTimeEncoded&	ioDateTime );


/**********************************************************************************************/
// VALUE STRING <=> VALUE DATETIME
//
FBL_SHARED_EXP void Convert_str_datetime( 
	const I_Value*	inValue, 
	I_Value*		outValue );


FBL_SHARED_EXP void Convert_str_datetime( 
	const I_Value*	inValue, 
	I_Value*		outValue );


#pragma mark === Value_datetime_imp ===


/**********************************************************************************************/
// This class implements I_ValueDateTime interface
// 
class FBL_SHARED_EXP_CLASS Value_datetime_imp : 
	public I_ValueDateTime, 
	public Value_Numeric< kTypeDateTime, vcDateTime, policyInPlace_llong >
{
		IMPLEMENT_UNKNOWN(Value_datetime_imp)											
		BEGIN_INTERFACE_TABLE(Value_datetime_imp)										
			IMPLEMENT_INTERFACE(I_Value)										
			IMPLEMENT_INTERFACE(I_ValueDateTime)										
			IMPLEMENT_INTERFACE(I_Serializable)										
		END_INTERFACE_TABLE()

	public://///////////////////////////////////////////////////////////////////////////////////

							Value_datetime_imp( 
								const DTFormat* 			inDTFormat = NULL );
							
							Value_datetime_imp( 
								const Value_datetime_imp&	inOther,
								const DTFormat*				inDTFormat = NULL );

virtual						~Value_datetime_imp( void );


	public://///////////////////////////////////////////////////////////////////////////////////

	// ---------------------
	// DateTimeFormat:

virtual	void				put_DTFormat( const DTFormat* inDTFormat ) throw();
virtual	const DTFormat*		get_DTFormat( void ) const throw();

	// ---------------------
	// Date properties:
	
virtual	long				get_Year( void ) const;
virtual	void				put_Year( long inYear );

virtual	ushort				get_Month( void ) const;
virtual	void				put_Month( ushort inMonth );

virtual	ushort				get_Day( void ) const;
virtual	void				put_Day( ushort inDay );

virtual	void				get_Date( 
								long&	outYear, 
								ushort& outMonth, 
								ushort& outDay ) const;

virtual	void				put_Date( 
								long	inYear, 
								ushort	inMonth, 
								ushort	inDay );

	// ---------------------
	// Time properties:

virtual	ushort				get_Hours( void ) const;
virtual	void				put_Hours( ushort inHours );

virtual	ushort				get_Minutes( void ) const;
virtual	void				put_Minutes( ushort inMinutes );

virtual	ushort				get_Seconds( void ) const;
virtual	void				put_Seconds( ushort inSeconds );

virtual	ushort				get_Milliseconds( void ) const;
virtual	void				put_Milliseconds( ushort inMilliseconds );

virtual	void				get_Time( 
								ushort& outHours, 
								ushort& outMinutes, 
								ushort& outSeconds,
								ushort& outMilliseconds ) const;

virtual	void				put_Time( 
								ushort 	inHours, 
								ushort 	inMinutes,
								ushort 	inSeconds, 
								ushort	inMilliseconds );

	// ---------------------
	// DateTime properties:
	
virtual	void				get_DateTime( 
								long&	outYear, 
								ushort& outMonth, 
								ushort& outDay,
								ushort& outHours, 
								ushort& outMinutes, 
								ushort& outSeconds,
								ushort& outMilliseconds ) const;
			
virtual	void				put_DateTime( 
								long	inYear, 
								ushort 	inMonth, 
								ushort 	inDay,
								ushort 	inHours, 
								ushort 	inMinutes,
								ushort 	inSeconds, 
								ushort	inMilliseconds );
							

	public://///////////////////////////////////////////////////////////////////////////////////

// I_Value API:

		using Value_Numeric< kTypeDateTime, vcDateTime, policyInPlace_llong >::Assign;


	// ---------------------
	// To/From string

virtual String				get_String( tslen inLimit = -1 ) const;
virtual void				put_String( const String& inStr );

virtual UChar*				get_String( 
								UChar*			outString, 
								tslen			inBufferChars =  -1 ) const;

virtual void				put_String( 
								const UChar* 	inStart,  
								const UChar* 	inEnd = NULL );

virtual char*				get_String( 
								char*			outString, 
								tslen			inBufferChars =  -1 ) const;

virtual void				put_String( 
								const char* 	inStart,  
								const char* 	inEnd = NULL );

virtual ulong				get_MaxChars( void ) const throw();

virtual void				put_Boolean( bool inValue ) 	{ argused1( inValue ); }
virtual bool				get_Boolean( void ) const 		{ return false; }

virtual void				put_Byte( uchar inValue )		{ argused1( inValue ); }
virtual uchar				get_Byte( void ) const			{ return ( uchar )( 0 ); }

virtual void				put_Short( short inValue )		{ argused1( inValue ); }
virtual short				get_Short( void ) const			{ return ( short )0; }

virtual void				put_UShort( ushort inValue )	{ argused1( inValue ); }
virtual ushort				get_UShort( void ) const		{ return ( ushort )( 0 ); }

virtual void				put_Medium( long inValue )		{ argused1( inValue ); }
virtual long				get_Medium( void ) const		{ return ( long )( 0 ); }

virtual void				put_Long( long inValue )		{ argused1( inValue ); }
virtual long				get_Long( void ) const			{ return ( long )( 0 ); }

virtual void				put_ULong( ulong inValue )		{ argused1( inValue ); }
virtual ulong				get_ULong( void ) const			{ return ( ulong )( 0 ); }

//virtual void				put_LLong( llong inValue )		{ argused1( inValue ); }
//virtual llong				get_LLong( void ) const			{ return mValue; }

virtual void				put_ULLong( ullong inValue )	{ argused1( inValue ); }
virtual ullong				get_ULLong( void ) const		{ return ( ullong )( 0 ); }

virtual void				put_Float( float inValue )		{ argused1( inValue ); }
virtual float				get_Float( void ) const			{ return ( float )( 0 ); }

virtual void				put_Double( double inValue )	{ argused1( inValue ); }
virtual double				get_Double( void ) const		{ return ( double )( 0 ); }

							
	public://///////////////////////////////////////////////////////////////////////////////////

// interface I_Serializable:

virtual void				From( I_IStream_Ptr inStream, bool inBlock = true )
							{
								argused1(inBlock);
								value_type* pv = PS::get_ValuePtr();
								inStream->get(*pv);
							}

virtual void				To( I_OStream_Ptr inStream, bool inBlock = true ) const
							{
								argused1(inBlock);
								const value_type* pv = PS::get_ValuePtr();
								inStream->put(*pv);
							}


	public://///////////////////////////////////////////////////////////////////////////////////

//#if FBL_TEST_CODE

virtual void				Init( void ) throw();
virtual void 				Increment( void ) throw(); 

//#endif // FBL_TEST_CODE


	protected://////////////////////////////////////////////////////////////////////////////////

		const DTFormat*		mDTFormat;			/// Date and time format.
		bool				mDTFormatOwner;
};


#pragma mark === Value_datetime ===


/**********************************************************************************************/
// Implements Value DateTime.
// 
class FBL_SHARED_EXP_CLASS Value_datetime : public Value_datetime_imp
{

public://///////////////////////////////////////////////////////////////////////////////////

							Value_datetime( 
								const DTFormat* 		inDTFormat = NULL );
							
							Value_datetime( 
								const Value_datetime&	inOther,
								const DTFormat*			inDTFormat = NULL );

							Value_datetime( 
								long	inYear, 
								ushort 	inMonth, 
								ushort 	inDay,
								ushort 	inHours, 
								ushort 	inMinutes,
								ushort 	inSeconds, 
								ushort	inMilliseconds,
								const DTFormat*		inDTFormat = NULL );

virtual						~Value_datetime( void );

virtual	I_Value_Ptr			Clone( bool inCopyData = true ) const throw();
};


#pragma mark === Value_datetime_null ===


/**********************************************************************************************/
// Implements nullable Value DateTime.
// 
class FBL_SHARED_EXP_CLASS Value_datetime_null : 
	public Value_datetime,
	protected policyNullable<policyInPlace_llong>
{

	public:///////////////////////////////////////////////////////////////////////////////////

		typedef policyNullable<policyInPlace_llong> PN;


	public:///////////////////////////////////////////////////////////////////////////////////

							Value_datetime_null( 
								const DTFormat* 			inDTFormat = NULL );
							
							Value_datetime_null( 
								const Value_datetime_null&	inOther,
								const DTFormat*				inDTFormat = NULL );

							Value_datetime_null( 
								long	inYear, 
								ushort 	inMonth, 
								ushort 	inDay,
								ushort 	inHours, 
								ushort 	inMinutes,
								ushort 	inSeconds, 
								ushort	inMilliseconds,
								const DTFormat*		inDTFormat = NULL );

virtual						~Value_datetime_null( void );


virtual	I_Value_Ptr			Clone( bool inCopyData = true ) const throw();

virtual bool				get_IsNullable( void ) const throw() { return true; }
virtual bool 				get_IsNull( void ) const throw();
virtual void 				put_IsNull( bool inValue ) throw();

	// ---------------------
	// Value compare methods:

virtual	int					Compare( 
								const I_Value& inOther,
								COMPARE_TYPE inCompareType = kNatureCompare ) const throw();
							
virtual String				get_String( tslen inLimit = -1 ) const;
virtual UChar*				get_String( 
								UChar* outString, 
								tslen inBufferChars = -1 ) const;

virtual char*				get_String( 
								char* outString, 
								tslen inBufferChars = -1 ) const;
};


/**********************************************************************************************/
FBL_End_Namespace

#include <VShared/FBL/publ/Headers/FBL_post_header.h>

#endif // _FBL_Value_DateTime_h
